﻿using DLL.MSDM.Entity.Param;
using DLL.NET.ComPort;
using DLL.NET.DJ.Entity;
using DLL.NET.DJ.MultyDJs;

using DLL.NET70.Infrastructure.Prism;
using DLL.NET70.Infrastructure.Prism.MVVM;
using DLL.Standard.Infrastructure.Log;

using Prism.Commands;
using Prism.Events;
using Prism.Ioc;
using Prism.Mvvm;
using Prism.Regions;

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO.Ports;
using System.Linq;
using System.Threading;
using System.Windows.Controls;

namespace Module.ExternalDevice.DuoJi.ViewModels
{
    public class PUC_DJ_ZL_MSViewModel : CMVVMBase, IRegionMemberLifetime
    {
        #region interface process

        private CDj_RunParams _obj = new CDj_RunParams();

        public CDj_RunParams Obj
        {
            get { return _obj; }
            set { SetProperty(ref _obj, value); }
        }

        private ObservableCollection<CDj_RunParam> _All = new ObservableCollection<CDj_RunParam>();

        public ObservableCollection<CDj_RunParam> All
        {
            get { return _All; }
            set { SetProperty(ref _All, value); }
        }

        private int _DJClosePosIndex = 0;

        public int DJClosePosIndex
        {
            get { return _DJClosePosIndex; }
            set { SetProperty(ref _DJClosePosIndex, value); }
        }

        //btnclick
        public DelegateCommand<object> BtnClickCommand { get; private set; }

        private void BtnClick(object button)
        {
            Button btn = (Button)button;
            string name = btn.Name;
            string openFlag = name.Substring(3, 2);
            string content = name.Substring(5, 2);
            int id = Convert.ToInt32(content);
            int open = 0;
            if (2 == Convert.ToInt32(openFlag))
            {
                open = 1;
            }
            else if (3 == Convert.ToInt32(openFlag))
            {
                //关位置1
                open = 2;
            }
            else if (4 == Convert.ToInt32(openFlag))
            {
                //关位置2
                open = 3;
            }
            CDj_RunParam oneDj = new CDj_RunParam();
            switch (id)
            {
                case 0:
                    {
                        oneDj = Obj.All[0];
                        break;
                    }
                case 1:
                    {
                        oneDj = Obj.All[1];
                        break;
                    }
                case 2:
                    {
                        oneDj = Obj.All[2];
                        break;
                    }
                case 3:
                    {
                        oneDj = Obj.All[3];
                        break;
                    }
                case 4:
                    {
                        oneDj = Obj.All[4];
                        break;
                    }

                default: break;
            }
            if (open == 1)
            {
                _multyDjCtrl.Open(oneDj.DjID, oneDj);
            }
            else if (open == 2)
            {
                _multyDjCtrl.Close(oneDj.DjID, oneDj, 0);
            }
            else if (open == 3)
            {
                _multyDjCtrl.Close(oneDj.DjID, oneDj, 1);
            }
        }

        //BtnClickOpenAllCommand
        public DelegateCommand<object> BtnClickOpenAllCommand
        {
            get { return new DelegateCommand<object>(BtnClickOpenAll).ObservesCanExecute(() => ComIsEnabled); }
        }

        private void BtnClickOpenAll(object button)
        {
            byte startId = StartID;
            int djCount = (EndID - StartID);
            _multyDjCtrl.OpenAllAscending(startId, djCount, Obj.All);
        }

        public DelegateCommand BtnClickCloseAllCommand
        {
            get { return new DelegateCommand(BtnClickCloseAll).ObservesCanExecute(() => ComIsEnabled); }
        }

        private void BtnClickCloseAll()
        {
            byte startId = StartID;
            int djCount = (EndID - StartID);
            _multyDjCtrl.CloseAllAscending(startId, djCount, Obj.All, DJClosePosIndex);
        }

        public DelegateCommand BtnClickOpenAndCloseAllCommand
        {
            get { return new DelegateCommand(BtnClickOpenAndCloseAll).ObservesCanExecute(() => ComIsEnabled); }
        }

        private void BtnClickOpenAndCloseAll()
        {
            byte startId = StartID;
            int djCount = (EndID - StartID);
            _multyDjCtrl.OpenAndCloseAllM1Ascending(startId, djCount, Obj.All, DJClosePosIndex);
        }

        private ObservableCollection<int> _pos = new ObservableCollection<int>();

        public ObservableCollection<int> Pos
        {
            get { return _pos; }
            set { SetProperty(ref _pos, value); }
        }

        public DelegateCommand<object> BtnReadPosClickCommand { get; private set; }

        private void BtnReadPosClick(object button)
        {
            Button btn = (Button)button;
            string name = btn.Name;
            string openFlag = name.Substring(3, 2);
            string content = name.Substring(5, 2);
            int id = Convert.ToInt32(content);

            CDj_RunParam oneDj = new CDj_RunParam();
            switch (id)
            {
                case 0:
                    {
                        oneDj = Obj.All[0];
                        break;
                    }
                case 1:
                    {
                        oneDj = Obj.All[1];
                        break;
                    }
                case 2:
                    {
                        oneDj = Obj.All[2];
                        break;
                    }
                case 3:
                    {
                        oneDj = Obj.All[3];
                        break;
                    }
                case 4:
                    {
                        oneDj = Obj.All[4];
                        break;
                    }

                default: break;
            }
            int cpos = 0;
            cpos = _multyDjCtrl.DJCtrlOne.ReadPos(oneDj.DjID);
            Pos[oneDj.DjID] = cpos;
        }

        #endregion interface process

        private IRegionManager _regionManager;
        private IContainerExtension _container;
        private IMultyDjCtrl _multyDjCtrl;

        private SerialSetting settings = new SerialSetting();

        public PUC_DJ_ZL_MSViewModel(IRegionManager regionManager,
            IEventAggregator ea,
            IApplicationCommands applicationCommands,
            IMultyDjCtrl mDjCtrl,

            IContainerExtension container
            ) : base(regionManager, ea, applicationCommands)
        {
            _container = container;
            _regionManager = regionManager;
            _multyDjCtrl = mDjCtrl;

            Title = "多工位配药机舵机";
            try
            {
                cb_ComNameSelectedChangedCommand = new DelegateCommand(CB_ComNameSelectedChanged);
                cb_BaudRateSelectedChangedCommand = new DelegateCommand(cb_BaudRateSelectedChanged);
            }
            catch (Exception e)
            {
                LogHelper.Warn("PUC_OpenComViewModel:" + e.Message);
            }

            #region delegate    com process command

            BtnReadPosClickCommand = new DelegateCommand<object>(BtnReadPosClick).ObservesCanExecute(() => ComIsEnabled);
            BtnClickCommand = new DelegateCommand<object>(BtnClick).ObservesCanExecute(() => ComIsEnabled);
            for (int i = 0; i < 10; i++)
            {
                Pos.Add(0);
            }
            _multyDjCtrl.ReadRunPosParam();
            //All = new ObservableCollection<CDj_RunParam>(_multyDjCtrl.runParams.All);
            Obj = (CDj_RunParams)_multyDjCtrl.runParams.Clone();

            #endregion delegate    com process command
        }

        #region LOAD

        private CDJ_Type djType = new CDJ_Type();

        public override void Loaded()
        {
            RegisterSaveCommand();
            _multyDjCtrl.ReadRunPosParam();
            //for (int i = 0; i < _multyDjCtrl.runParams.All.Count; i++)
            //{
            //    Obj.All.Add((CDj_RunParam)_multyDjCtrl.runParams.All[i].Clone());
            //    All[i] = ((CDj_RunParam)_multyDjCtrl.runParams.All[i].Clone());
            //}

            Obj = (CDj_RunParams)_multyDjCtrl.runParams.Clone();
            _multyDjCtrl.DJCtrlOne.SerialPortManager.CurrentSerialSettings.UpdatePortName();

            settings = _multyDjCtrl.DJCtrlOne.SerialPortManager.CurrentSerialSettings;
            ComNames = settings.PortNameCollection;
            BaudRates = settings.BaudRateCollection;
            _multyDjCtrl.DJCtrlOne.ReadComParam();
            ComName = settings.cSerialEntity.PortName;
            BaudRate = settings.cSerialEntity.BaudRate;
            base.Loaded();
        }

        public override void UnLoaded()
        {
            UnRegisterSaveCommand();
            CloseCom();
            base.UnLoaded();
        }

        #endregion LOAD

        public bool KeepAlive
        {
            get
            {
                //return false;//这个的作用是，只要离开当前切面，就注销掉当前页面
                return false;//这个的作用是，只要离开当前切面，就注销掉当前页面
            }
        }

        #region Com name   Process

        private bool _OpenComEnabled = true;

        public bool OpenComEnabled
        {
            get { return _OpenComEnabled; }
            set
            {
                SetProperty(ref _OpenComEnabled, value);
            }
        }

        private bool _isEnabled = false;

        public bool ComIsEnabled
        {
            get { return _isEnabled; }
            set
            {
                SetProperty(ref _isEnabled, value);
            }
        }

        private string _comName = "COM1";

        public string ComName
        {
            get { return _comName; }
            set { SetProperty(ref _comName, value); }
        }

        //ComNames
        private string[] _comNames;

        public string[] ComNames
        {
            get { return _comNames; }
            set { SetProperty(ref _comNames, value); }
        }

        private object _cb_ComNameSelectItem;

        public object cb_ComNameSelectItem
        {
            get { return _cb_ComNameSelectItem; }
            set { SetProperty(ref _cb_ComNameSelectItem, value); }
        }

        public int _BaudRate = 9600;

        public int BaudRate
        {
            get { return _BaudRate; }
            set { SetProperty(ref _BaudRate, value); }
        }

        private BindingList<int> _baudRates = new BindingList<int>();

        public BindingList<int> BaudRates
        {
            get { return _baudRates; }
            set { SetProperty(ref _baudRates, value); }
        }

        private object _cb_BaudRateSelectItem;

        public object cb_BaudRateSelectItem
        {
            get { return _cb_BaudRateSelectItem; }
            set { SetProperty(ref _cb_BaudRateSelectItem, value); }
        }

        public DelegateCommand cb_ComNameSelectedChangedCommand { get; private set; }

        private void CB_ComNameSelectedChanged()
        {
            if (cb_ComNameSelectItem != null)
            {
                ComName = cb_ComNameSelectItem.ToString();
                settings.cSerialEntity.PortName = ComName;
            }
        }

        public DelegateCommand cb_BaudRateSelectedChangedCommand { get; private set; }

        private void cb_BaudRateSelectedChanged()
        {
            if (cb_BaudRateSelectItem != null)
            {
                BaudRate = Convert.ToInt32(cb_BaudRateSelectItem.ToString());
                settings.cSerialEntity.BaudRate = BaudRate;
            }
        }

        private string _connectedStateBrush = "Gray";

        public string ConnectedStateBrush
        {
            get { return _connectedStateBrush; }
            set { SetProperty(ref _connectedStateBrush, value); }
        }

        public DelegateCommand OpenComCommand
        { get { return new DelegateCommand(OpenCom).ObservesCanExecute(() => OpenComEnabled); } }

        public DelegateCommand CloseComCommand
        { get { return new DelegateCommand(CloseCom).ObservesCanExecute(() => ComIsEnabled); } }

        private void OpenCom()
        {
            bool ret = _multyDjCtrl.DJCtrlOne.OpenCom(ComName, Convert.ToInt32(BaudRate));
            if (false == ret)
            {
                LogMessage("串口打开失败！");
                return;
            }
            if (_multyDjCtrl.DJCtrlOne.SerialPortManager.IsOpen == true)
            {
                ConnectedStateBrush = "Green";
                ComIsEnabled = true;
                OpenComEnabled = false;
                ThreadStartEnabled = true;
            }
            else
            {
                ConnectedStateBrush = "Gray";
                ComIsEnabled = false;
                ThreadStartEnabled = false;
            }
            LogMessage("串口打开成功！");
        }

        private void CloseCom()
        {
            try
            {
                if (_multyDjCtrl.DJCtrlOne.SerialPortManager.IsOpen == true)
                {
                    _multyDjCtrl.DJCtrlOne.SerialPortManager.CloseCom();
                }
                if (_multyDjCtrl.DJCtrlOne.SerialPortManager.IsOpen == true)
                {
                    ConnectedStateBrush = "Green";
                    ComIsEnabled = true;
                }
                else
                {
                    ConnectedStateBrush = "Gray";
                    ComIsEnabled = false;
                }
            }
            catch (Exception e)
            {
                LogMessage("关闭串口出现异常：" + e.Message);
            }
            OpenComEnabled = true;
            ThreadStartEnabled = false;
        }

        public DelegateCommand SaveComCommand
        {
            get { return new DelegateCommand(SaveCom); }//.ObservesCanExecute(() => IsEnabled);
        }

        private void SaveCom()
        {
            if ((ComName.Length > 0) && (BaudRate > 0))
            {
                settings.cSerialEntity.BaudRate = BaudRate;
                settings.cSerialEntity.PortName = ComName;
                _multyDjCtrl.DJCtrlOne.SerialPortManager.CurrentSerialSettings = settings;
                _multyDjCtrl.DJCtrlOne.SaveComParam();

                LogMessage("串口参数保存成功！");
            }
            else
            {
                LogMessage("串口参数保存失败！");
            }
        }

        #endregion Com name   Process

        #region com baudrate variable

        public override void Save()
        {
            _multyDjCtrl.runParams = Obj;
            _multyDjCtrl.SaveRunPosParam();
            _multyDjCtrl.SaveComParam();
            LogMessage("舵机参数保存成功！");
        }

        #endregion com baudrate variable

        #region loop run property

        private bool _ThreadStartEnabled = false;

        public bool ThreadStartEnabled
        {
            get { return (_ThreadStartEnabled); }
            set
            {
                SetProperty(ref _ThreadStartEnabled, value);
            }
        }

        private bool _ThreadStopEnabled = false;

        public bool ThreadStopEnabled
        {
            get { return (_ThreadStopEnabled); }
            set
            {
                SetProperty(ref _ThreadStopEnabled, value);
            }
        }

        private int _LoopCount = 10;

        public int LoopCount
        {
            get { return _LoopCount; }
            set { SetProperty(ref _LoopCount, value); }
        }

        private int _LoopIndex = 0;

        public int LoopIndex
        {
            get { return _LoopIndex; }
            set { SetProperty(ref _LoopIndex, value); }
        }

        private byte _StartID = 0;

        public byte StartID
        {
            get { return _StartID; }
            set { SetProperty(ref _StartID, value); }
        }

        private byte _EndID = 5;

        public byte EndID
        {
            get { return _EndID; }
            set { SetProperty(ref _EndID, value); }
        }

        #endregion loop run property

        #region 舵机状态属性变量

        private string _Voltage = "0";

        public string Voltage
        {
            get { return _Voltage; }
            set { SetProperty(ref _Voltage, value); }
        }

        private string _Current = "0";

        public string Current
        {
            get { return _Current; }
            set { SetProperty(ref _Current, value); }
        }

        private string _Power = "0";

        public string Power
        {
            get { return _Power; }
            set { SetProperty(ref _Power, value); }
        }

        private string _Temperature = "0";

        public string Temperature
        {
            get { return _Temperature; }
            set { SetProperty(ref _Temperature, value); }
        }

        private string _Status = "0";

        public string Status
        {
            get { return _Status; }
            set { SetProperty(ref _Status, value); }
        }

        #endregion 舵机状态属性变量

        #region loop run function

        public DelegateCommand LoopRunCommand
        {
            get { return new DelegateCommand(LoopRun).ObservesCanExecute(() => ThreadStartEnabled); ; }
        }

        private void LoopRun()
        {
            if (true == StopLoop)
            {
                StopLoop = false;
                //开启线程
                Thread thread = new Thread(new ThreadStart(ThreadLoopRun));//创建线程
                thread.Start();
                ThreadStopEnabled = true;
                ThreadStartEnabled = false;
            }
        }

        private void ThreadLoopRun()
        {
            for (int i = 0; i < LoopCount; i++)
            {
                LoopIndex = i + 1;
                if (true == StopLoop)
                {
                    _multyDjCtrl.CloseAllAscending(StartID, (EndID - StartID), DJClosePosIndex);
                    ThreadStopEnabled = false;
                    ThreadStartEnabled = true;
                    return;
                }

                _multyDjCtrl.OpenAllAscending(StartID, (EndID - StartID));
                _multyDjCtrl.CloseAllAscending(StartID, (EndID - StartID), DJClosePosIndex);
                Thread.Sleep(10 * 1000);
            }
            _multyDjCtrl.CloseAllAscending(StartID, (EndID - StartID), DJClosePosIndex);
            StopLoop = true;
            ThreadStopEnabled = false;
            ThreadStartEnabled = true;
        }

        public DelegateCommand LoopStopCommand
        {
            get { return new DelegateCommand(LoopStop).ObservesCanExecute(() => ThreadStopEnabled); ; }
        }

        private bool StopLoop = true;

        private void LoopStop()
        {
            StopLoop = true;
        }

        #endregion loop run function
    }
}